import functools
import json
import random
import string
import time
from application.tools.comm import get_ali_object
import requests

from app import db
from application.tools.comm import sendMsg
from captcha.image import ImageCaptcha
from flask import Blueprint, request, send_file, jsonify, redirect
from application.models.users.user import *
from application.tools.myredis import r
from application.tools.myjwt import myjwt

user_blue = Blueprint("userblue", __name__,url_prefix='/user')

# 权限认证
# 不带参数装饰器
# def islogin(func):
#     @functools.wraps(func)
#     def wrapper():
#         func()
#         # 权限验证判断，如果有问题返回
#         return func()
#     return wrapper
# 带参数装饰器
# def islogin(type):
#     def pemistion(func):
#         @functools.wraps(func)
#         def wrapper():
#             func()
#             if type == 1:
#                 return redirect("http://www.baidu.com")
#             else:
#                 return redirect("http://www.jd.com")
#         return wrapper
#     return pemistion
#
# @user_blue.route('/test')
# @islogin(1)
# def test():
#     print("执行test")
#     return jsonify({'code':200,'mes':'mes'})


# 获取图形验证码
@user_blue.route("/getcode", methods=["GET"])
# @islogin(2)
def getcode():
    img_code = "".join(random.sample(string.digits+string.ascii_letters, 4)) # 随机获取字符串+数字的的4个字符
    cap = ImageCaptcha() # 生成图形验证码
    img = cap.generate(img_code) # 使用生成图片
    # 从页面中获取uuid作为redis key
    uuid = str(request.args.get("uuid"))
    # 写入redis
    r.str_add(uuid, str(img_code), 60)

    return send_file(img, 'image/png')



# 发送短信验证码
@user_blue.route('/sendSmsCode', methods=['POST'])
def sendSmsCode():
    data = request.data
    # 校验前端传来的参数
    if data:
        data = json.loads(data)
        # 获取3个参数
        mobile = data.get("mobile")
        img_code = data.get("piccode")
        uuid = data.get("uuid")
        print("img_code=======================", img_code, uuid, mobile)
        # 通过uuid查询
        value = r.str_get(uuid)
        print("value=======================", value)
        # 判断图形验证码是否存在
        if value:
            # 校验短信验证码
            if value.lower() == img_code.lower():
                # 验证短信验证码一分钟只能发送一次
                sms_code = r.str_get(mobile)
                # 判断手机号是否一分钟发送验证码
                if sms_code:
                    return jsonify({"code": 10013, "msg": "一分钟之内不能重复发送"})
                # 生成短信验证码
                scode = random.randint(100000, 999999)
                # 调用短信发送平台
                flag = sendMsg(mobile, scode)
                if flag == True:
                    # 存入redis数据库中
                    r.str_add(mobile, scode, 60)
                    # 删除图形验证码
                    r.str_del(uuid)
                    # 返回结果
                    return jsonify({"code": 200, "msg": "发送成功"})
                else:
                    return jsonify({"code": 10001, "msg": "发送失败"})
            return jsonify({"code": 10012, "msg": "图形验证码错误"})

        else:
            return jsonify({"code": 10011, "msg": "图形验证码不存在"})
        # 校验图形验证码是否正确
    else:
        return jsonify({"code": 10010, "msg": "参数错误"})

# 注册登录接口
@user_blue.route("/login", methods=["POST"])
def login():
    #获取参数，手机号，验证码
    data = request.data
    # 校验前端参数
    if data:
        data = json.loads(data)
        # 获取 手机号，验证码
        mobile = data['mobile']
        code = data['code']
        # 根据手机号去redis获取验证码
        code = r.str_get(mobile)
        # 校验验证码是否存在
        if code:
            # 验证码是否相同, # 如果不相同返回错误
            if int(code) == int(code):
                # 如果相同查询数据库user表
                # 如果存在返回用户信息
                # 如果不存在写入用户表

                # 查询手机号是否存在
                user = User.query.filter(User.mobile == mobile).first()
                # 判断是否获取过来数据
                if user:
                    # 删除redis中存储的短信验证码
                    r.str_del(mobile)
                # 如果不存在，就进行添加该用户
                else:
                    u = User(mobile=mobile,nikename=mobile)
                    db.session.add(u)
                    db.session.commit()
                    user = User.query.filter(User.mobile == mobile).first()
                # 用用户信息生成jwt token
                token = myjwt.jwt_encode(data={"data":{'uid':user.id,'exp':int(time.time())}})
                # 返回信息给页面
                return jsonify({'code':200,'token':token,'userid':user.id})
            # 返回短信验证码错误
            else:
                return jsonify({"code": 10021, 'msg': '短信验证码错误'})
        # 如果验证码不存在返回结果
        else:
            return jsonify({"code": 10020, "meg": ""})
    # # 返回参数错误
    # return jsonify({"code": 10002, 'meg': "请输入，正确的数据"})


# 获取weibo地址
@user_blue.route('/getwburl')
def getwburl():
    client_id = "3674019597"
    redirect_uri = "http://127.0.0.1:8000/user/weiboCallback/"
    url = "https://api.weibo.com/oauth2/authorize?client_id=%s&r esponse_type=code&redirect_uri=%s"%(client_id,redirect_uri)
    return jsonify({"code":200,"url":url})

@user_blue.route('/weiboCallback/')
# weibo回调接口
def weiboCallback():
    mes = request.args
    # 获取code
    # code = request.args.get('code')
    # # 向access_token接口发起post请求
    # data = {"client_id":'3674109597',"client_secret":"7ae99bc0d54ead29fc8d1b9fabd78587",
    #         "grant_type":"authorization_code",
    #         'redirect_uri':"http://127.0.0.1:8000/user/weiboCallback/",'code':code}
    # res = requests.post('https://api.weibo.com/oauth2/access_token',data=data)
    # print(">>>>>>>>",res.text)
    # # 解析参数，token,uuid
    # mes = json.loads(res.text)
    token = mes['access_token']
    uid = mes['uid']
    # 查询三方登陆中uid是否存在，如果存在，查询用户表，用用户信息生成token跳转到vue页面
    sql = "select user.id from user inner join sf_login on user.id=sf_login.userid where sf_login.uid='%s'"%(uid)
    user = db.session.execute(sql)
    # 判断是否查询到
    # if user:
    #     print('***')
    #     for i in user:
    #         data = {"data":{"user.id":i[0],"exp":int(time.time())}}
    #         token = myjwt.jwt_encode(data)
    #         return redirect("http://localhost:8080/#/updateToken?userid="+str(i[0])+"&token="+token)

    # 不存在跳转到vue绑定页面，token uuid传递过去
    return redirect('http://localhost:8080/#/bindMobile?uid='+uid+"&token="+token)

# 绑定手机号
@user_blue.route("/bindMobile",methods=['POST'])
def bindMobile():
    data = json.loads(request.data)
    mobile = data['mobile']
    uid = data['uid']
    token = data['token']
    # 先查询用户表，如果手机号存在
    user = User.query.filter(User.mobile == mobile).first()
    if not user:
        # 添加用户
        u = User(mobile=mobile,nikename=mobile)
        db.session.add(u)
        db.session.commit()
        # 获取用户信息
        user = User.query.filter(User.mobile == mobile).first()

    sfuser = SfLogin(userid=user.id,webfrom='wb',uid=uid,token=token)
    db.session.add(sfuser)
    db.session.commit()
    # 如果不存在，写入user表
    # 获取userid，写入三方登录表，生成token返回
    data = {"data":user.id,"exp":int(time.time())}
    token = myjwt.jwt_encode(data)
    return jsonify({"userid":str(user.id),'token':token})


# 购买vip生成订单
@user_blue.route("/buy",methods=['POST'])
def buy():
    # 获取参数
    data = json.loads(request.data)
    userid = data['userid']
    year = data['year']
    money = 200
    # 生成vip订单
    dmoney = money * int(year)
    order_no = str(int(time.time()))+str(userid)+str(random.randint(100,999))
    a = VipRecord(userid=userid,year=year,money=dmoney,active_money=dmoney,status=1)
    db.session.add(a)
    db.session.commit()
    # 支付，返回支付url
    pay = get_ali_object()
    # 生成支付的url
    query_params = pay.direct_pay(
        subject="test",  # 商品简单描述
        out_trade_no=str(order_no),  # 用户购买的商品订单号（每次不一样） 20180301073422891
        total_amount=float(100.00),  # 交易金额(单位: 元 保留俩位小数)
    )
    pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
    return jsonify({"code":200,"url":pay_url})

import time
@user_blue.route('/callback')
def callback():
    # 接收参数
    data = request.args
    datames = {k:v for k,v in data.items()}
    # 删除字典中key为sign的记录
    sign = datames.pop('sign')
    # 鉴权    订单  流水号
    pay = get_ali_object()
    flag = pay.verifl(datames.sign)

    if flag == True:
        # 支付宝流水号
        transaction_no = datames['trade_no']
        # 订单号
        order_no = datames['out_trade_no']
        # 事务处理
        try:
            # 订单更新订单表
            record = VipRecord.query.filter_by(order_no = order_no).first()

            # 更新vip表
            vip = Vip.query.filter(Vip.userid == record.userid,Vip.status==1).first()
            if vip is not None:
                # 结束时间 + 购买年限
                etime = vip.e_time.split("-")
                tyear = int(etime[0]+int(record.year))
                yearstr = "-"
                etime[0] = str(tyear)
                retime = yearstr.join(etime)
                vip.e_time = retime
                db.session.add(vip)
            else:
                nowyear = datetime.date.strftime(datetime.datetime.now(),"%Y-%m-%d %H:%m:%s")
                etime = nowyear.split("-")
                tyear = int(etime[0])+int(record.year)
                etime[0] = str(tyear)
                yearstr = "-"
                retime = yearstr.join(etime)

                vip = Vip(userid=record.userid,s_time=datetime.datetime.now(),e_time=retime)
                db.session.add(vip)
            db.session.commit()
        except:
            db.session.rollback()
    else:
        print("鉴权失败")
    return "ok"


# 渲染 -- 添加课程及类别
@user_blue.route('/getTags')
def getTags():
    tags = Tags.query.all()
    tagslist = [{"id":i.id,"name":i.name} for i in tags]

    types = Ctype.query.all()
    typeslist = [{"id":i.id,"name":i.name} for i in types]

    ctype = CourseType.query.all()
    clist = [{"id":i.id,"name":i.name,} for i in ctype]
    return jsonify({"code":200,"tags":tagslist,"types":typeslist,"ctype":clist})

from qiniu import Auth, put_file, etag
import qiniu.config
# 上传图片
@user_blue.route('/get_qntoken')
def getimg():
    # 需要填写你的 Access Key 和 Secret Key
    access_key = '1VRUxr2mVM8tIYF35FFZMsMNT9c7vXWYl4emI2h3'
    secret_key = 'd7BmNv7m79OtJuBzV9UJ9IWRbFj1ftXEv5wncp-H'
    # 构建鉴权对象
    q = Auth(access_key, secret_key)
    # 要上传的空间
    bucket_name = 'swh-syl'

    token = q.upload_token(bucket_name)
    return jsonify({'code':200,'token':token})


@user_blue.route('/addCourse',methods=['POST'])
def addCours():
    try:
        # 获取参数
        data = json.loads(request.data)
        # 写入课程表
        course = Course(name=data['name'],url=data['url'],descrip=data['desc'],ctype=data['type'])
        db.session.add(course)
        # 获取新加的课程id
        scourse = Course.query.filter_by(name = data['name']).first()
        # 写入课程标签表
        for i in data['tags']:
            sql = "insert into course_tag(courseid,tagid) values(%d,%d)"%(int(scourse.id),int(i))
            db.session.execute(sql)
        # 写入课程分类表
        for i in str(data['ctype']):
            sql = "insert into course_cate(courseid,course_typeid) values(%d,%d)"%(int(scourse.id),int(i))
            db.session.execute(sql)
        db.session.commit()
    except:
        db.session.rollback()
    return jsonify({'code':200})



import math
@user_blue.route('/getCourse')
def getCourse():
    # 获取当前页数
    page = int(request.args.get('page'))
    # 获取上线、即将上线条件
    online = request.args.get('is_publish')
    # 获取排序字段
    orderpara = request.args.get('orderpara')
    # 查询总条数
    total = Course.query.count()
    # 定义每页显示多少条
    page_size = 2
    # 查询当前页记录
    start = math.ceil((page-1)*page_size)
    # select * from course limit start,page_size
    if orderpara == 'new':
        course = Course.query.order_by(Course.create_time.desc()).filter(Course.is_publish==online).offset(start).limit(page_size).all()
    else:
        course = Course.query.order_by(Course.views.desc()).filter(Course.is_publish == online).offset(start).limit(
            page_size).all()
    list = [{"id":i.id,'name':i.name,'url':i.url,'views':i.views,} for i in course]
    # 返回结果
    return jsonify({'code':200,'clist':list,'total':total,'page_size':page_size})
